﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PluggableModulesInterface;
using StorageManagement;
using Settings;
using SMSROUTER.Business;
using System.Configuration;
using Utils;
using System.Data.Linq;
using System.Data;
using System.Xml;
using PluggableModulesRouter;
using SMSROUTER.StorageManagement;

namespace MORouterTVSI
{
    public class Router : WorkingBaseMORouter
    {
        #region Properties and Fields
        private SMS8x25Service.SMS8x25Service _SmsRouterObject = new SMS8x25Service.SMS8x25Service();
        #endregion

        protected override void SendSms(List<SmsInWaiting> listSms, CooperateProvider cooperate, SmsWebService smsWebService)
        {
            try
            {
                int threadId = ThreadID;
                _SmsRouterObject.Timeout = smsWebService.TimeOut != null ? smsWebService.TimeOut.Value : this.ServiceTimeOut;
                _SmsRouterObject.Url = smsWebService.URLWebService;

                string[][] guidReturn = new string[][] { };
                string msgReturn = "";

                DataSet ds = new DataSet();
                DataTable dt = new DataTable();
                dt.TableName = "SMSIn";
                dt.Columns.Add("Subs", typeof(string));
                dt.Columns.Add("Message", typeof(string));
                dt.Columns.Add("ShortCode", typeof(string));
                dt.Columns.Add("ReceivedTime", typeof(DateTime));
                dt.Columns.Add("Status", typeof(string));
                dt.Columns.Add("OperatorID", typeof(int));
                dt.Columns.Add("SmsInGUID", typeof(Guid));
                dt.Columns.Add("CooperateID", typeof(int));
                ds.Tables.Add(dt);

                foreach (var item in listSms)
                {
                    DataRow dr = dt.NewRow();
                    dr["Subs"] = item.Subs;
                    dr["Message"] = item.Message;
                    dr["ShortCode"] = item.ShortCode;
                    dr["ReceivedTime"] = item.ReceivedTime;
                    dr["Status"] = item.Status;
                    dr["OperatorID"] = item.OperatorID;
                    dr["SmsInGUID"] = item.SmsInGUID;
                    dr["CooperateID"] = item.CooperateID;
                    dt.Rows.Add(dr);
                }

                string publicKey = cooperate.MOPublicKey;
                //Chuyển DataSet thành XML
                XmlElement xml = Xml.Serialize(ds);
                string bitStrengthString = publicKey.Substring(0, publicKey.IndexOf("</BitStrength>") + 14);
                publicKey = publicKey.Replace(bitStrengthString, "");
                int bitStrength = int.Parse(bitStrengthString.Replace("<BitStrength>", "").Replace("</BitStrength>", ""));
                string inputString = xml.OuterXml;
                //Sinh MD5 cho chuỗi xml - Hàm SendEncryptSMSMessage sẽ giải mã chuỗi XML sau đó kiểm tra CheckSum xem nội dung có bị thay đổi không
                string checksum = inputString.ToMD5Hash();
                //Mã hóa XML bằng PublicKey
                inputString = inputString.ToRSAEncryptString(bitStrength, publicKey);
                //tạo chuỗi trans
                string stransID = Guid.NewGuid().ToString();

                int result = _SmsRouterObject.SentEncryptMO(stransID, cooperate.CooperateID, inputString, checksum, ref guidReturn, ref msgReturn);
                if (guidReturn.Length > 0)
                {
                    for (int i = 0; i < guidReturn[0].Length; i++)
                    {
                        Guid retGUID = Guid.Parse(guidReturn[0][i]);
                        var item = listSms.Find(p => p.SmsInGUID == retGUID);
                        if (item != null)
                        {
                            string message = guidReturn[1][i];
                            if (message.StartsWith("true", StringComparison.CurrentCultureIgnoreCase))
                            {
                                SmsInStatisticStorage.EnqueueElementData(this.Key, new SmsInStatisticStruct(AppSetting.Status.SENTPARTNER, item.SmsInGUID, item.RetryOnFailReqTimes, item.RetryOnTimeOutReqTimes, item.RetryOnFailReqDuration, item.RetryOnTimeOutReqDuration, threadId, this.Key, DateTime.Now));
                            }
                            else
                            {
                                RetryOnFailure(item, message);
                            }
                        }
                    }
                }
                else
                {
                    InsertLog(new Exception("GuidReturn.Length == 0"), cooperate, smsWebService);
                    RetryOnFailure<SmsInWaiting>(listSms, "GuidReturn.Length == 0");
                }
            }
            catch (Exception ex)
            {
                InsertLog(ex, cooperate, smsWebService);
                HandleException<SmsInWaiting>(ex, AppSetting.WarningType.mo_error, listSms);
            }
        }

        void InsertLog(Exception ex, CooperateProvider cooperate, SmsWebService smsWebService)
        {
            Log.InsertLog(string.Format("CooperateID={0}; RouterID={1}; URL=\"{2}\"; Timeout = {3};| Error: {4}",
                cooperate.CooperateID, this.Key, this._SmsRouterObject.Url, this._SmsRouterObject.Timeout, ex.Message),
                "MORouterTVSI.Router.SendSms", this.ObjectType, AppSetting.WarningType.mo_error, cooperate.CooperateID);
        }
    }
}